Skip to content

FEATURE: Support long type expiration time in v2 APIs#1101

Open
f1v3-dev wants to merge 1 commit into
naver:developfrom
f1v3-dev:feat/v2-long-type-exp
Open

FEATURE: Support long type expiration time in v2 APIs#1101
f1v3-dev wants to merge 1 commit into
naver:developfrom
f1v3-dev:feat/v2-long-type-exp

Conversation

@f1v3-dev

@f1v3-dev f1v3-dev commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

🔗 Related Issue

⌨️ What I did

v2 API의 만료 시간 (expiration time) 파라미터 타입을 int 에서 long 으로 변경합니다.
이를 통해 int 범위를 넘는 Unix timestamp 기반 만료 시각(e.g. 2038년 이후 절대 시각)을 사용할 수 있습니다.

  • KV Store API: long exp 를 받도록 변경
  • Collection Create / Insert API: long 만료 시간을 담는 AttributesCreate 도입
  • 내부 operation 계층: OperationFactory, ops/*Operation -> getExpiration method, `ASCII / Binary 프로토콜 구현체까지 타입 변경
    • ASCII는 만료 시간을 텍스트로 전송하므로 long 값을 그대로 사용
    • Binary 프로토콜은 int 범위를 넘는 값은 예외 처리

기존 API(MemcachedClient, ArcusClient)는 변경되지 않으며 int 만료 파라미터가 long 으로 자동 형 변환(auto-widening)이 되어 기존 사용자 코드에는 영향이 없습니다.

@f1v3-dev f1v3-dev requested a review from oliviarla July 7, 2026 10:41
@f1v3-dev f1v3-dev self-assigned this Jul 7, 2026
@f1v3-dev

f1v3-dev commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

속성 타입 구조 정리 (as-is → to-be)

타입 역할 expireTime 상태
Attributes (v1) v1 setattr 입력 Integer 유지 (implements AttributeClause만 추가)
CollectionAttributes (v1) v1 create/insert/setattr 입력 + getattr 출력 Integer 유지
AttributesCreate (신규) v2 create/insert 입력 long 신규
AttributesUpdate (신규) v2 setattr 입력 (부분갱신) long 신규
AttributesResult (신규) v2 getattr 출력 long 신규

AS-IS (기존)

v1은 한 클래스 계열(Attributes / CollectionAttributes) 이 모든 역할을 가지고 있는 상태

CollectionAttributes (extends Attributes)   ← expireTime: Integer (int 범위 한계)
   ├─ create 입력      (asyncBopCreate ...)
   ├─ insert 입력      (asyncBopInsert ...)
   ├─ setattr 입력     (asyncSetAttr)
   └─ getattr 출력     (asyncGetAttr 반환)
  • 입력/출력이 한 객체에 섞여 있고, expireTimeInteger라 int 범위를 넘는 만료 시각을 표현할 수 없음.

TO-BE (변경 후)

v1은 그대로 두고, v2는 역할별로 분리 + long 기반으로 로 재설계

[v1 — 변경 X]

  • Attributes / CollectionAttributes (Integer expireTime, 기존 API 전용)
    • Attributes 에 implements AttributeClause 만 추가 (setAttr 호환을 위한 인터페이스만 추가)

[v2 — 신규, long]

  • AttributesCreate
    • 생성(create/insert) 클래스
    • long expTime, primitive + 기본값
  • AttributesResult
    • 조회(getAttr) 클래스
    • immutable, 조회 전용 필드 포함, BKey 정보 포함
  • AttributesUpdate
    • 수정(setAttr) 클래스
    • 부분 갱신을 위해 null을 허용하는 Wrapper Class + maxBkeyRange
  • AttributeClause (interface)
    • 수정(setAttr) Operation을 생성할 때 기존 Attributes와 새로 만든AttributesUpdate 를 모두 받기 위한 인터페이스

역할 분리 요약

동작 AS-IS (v1 공용) TO-BE (v2)
create / insert 입력 CollectionAttributes AttributesCreate
setattr 입력 CollectionAttributes AttributesUpdate (부분갱신)
getattr 출력 CollectionAttributes AttributesResult (조회 전용)

@oliviarla oliviarla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다음은 클래스명 제안인데, @jhpark816 님도 함께 고민해주시면 좋겠습니다.

AttributeClause -> AttributesIF
AttributesCreate -> CreateAttrs
AttributesUpdate -> UpdateAttrs
AttributeResult -> Attrs (v2 인터페이스에서 getAttrs, setAttrs 메서드를 제공하는 가정 하)

지금은 인자명, 변수명이 제각각인데 클래스명이 결정된 후에 변수명을 하나로 통일하면 될 것 같습니다.

Comment thread src/main/java/net/spy/memcached/OperationFactory.java
Comment thread src/test/java/net/spy/memcached/v2/KVAsyncArcusCommandsTest.java Outdated
Comment thread src/main/java/net/spy/memcached/collection/CollectionCreate.java Outdated
Comment thread src/main/java/net/spy/memcached/collection/CollectionCreate.java Outdated
Comment thread src/main/java/net/spy/memcached/v2/attribute/UpdateAttributes.java
@jhpark816

Copy link
Copy Markdown
Collaborator

다음은 클래스명 제안인데, @jhpark816 님도 함께 고민해주시면 좋겠습니다.

AttributeClause -> AttributesIF
AttributesCreate -> CreateAttrs
AttributesUpdate -> UpdateAttrs
AttributeResult -> Attrs (v2 인터페이스에서 getAttrs, setAttrs 메서드를 제공하는 가정 하)

질문을 먼저 합니다.

  • 아래 클래스가 v2에서 어떻게 사용되는 지 보기 위해, getAttrs, setAttrs 메서드를 제공해 주면 좋겠습니다.
    • AttributesUpdate
    • AttributeResult
  • 위의 2 클래스를 역할에 따라 분리하는 것이 맞나요?
  • Interface 부분을 보니 getLength()만 있네요. 반드시 필요한가요?

@f1v3-dev f1v3-dev force-pushed the feat/v2-long-type-exp branch from 966c773 to df3b226 Compare July 9, 2026 03:05
@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

아래 클래스가 v2에서 어떻게 사용되는 지 보기 위해, getAttrs, setAttrs 메서드를 제공해 주면 좋겠습니다.

  • AttributesUpdate
  • AttributeResult

인터페이스와 구현 코드 첨부합니다.

v2 - setAttributes API

AsyncArcusCommandsIF.java

/**
 * Set the attributes of the item stored at the given key.
 *
 * @param key        the key
 * @param attributes the attributes to set
 * @return {@code true} if the attributes were set, otherwise {@code false}
 */
ArcusFuture<Boolean> setAttributes(String key, AttributesUpdate attributes);

AsyncArcusCommands.java

  @Override
  public ArcusFuture<Boolean> setAttributes(String key, AttributesUpdate attributes) {
    AbstractArcusResult<Boolean> result = new AbstractArcusResult<>(new AtomicReference<>());
    ArcusFutureImpl<Boolean> future = new ArcusFutureImpl<>(result);
    ArcusClient client = arcusClientSupplier.get();

    OperationCallback cb = new OperationCallback() {
      @Override
      public void receivedStatus(OperationStatus status) {
        switch (status.getStatusCode()) {
          case SUCCESS:
            result.set(true);
            break;
          case ERR_NOT_FOUND:
            result.set(false);
            break;
          case CANCELLED:
            future.internalCancel();
            break;
          default:
            /*
             * ATTR_ERROR or unknown statement.
             */
            result.addError(key, status);
        }
      }

      @Override
      public void complete() {
        future.complete();
      }
    };
    Operation op = client.getOpFact().setAttr(key, attributes, cb);
    future.setOp(op);
    client.addOp(key, op);

    return future;
  }

v2 - getAttributes API

AsyncArcusCommandsIF.java

/**
 * Get the attributes of the item stored at the given key.
 *
 * @param key the key
 * @return the {@link AttributesResult} of the item, or {@code null} if not found
 */
ArcusFuture<AttributesResult> getAttributes(String key);

AsyncArcusCommands.java

  @Override
  public ArcusFuture<AttributesResult> getAttributes(String key) {
    keyValidator.validateKey(key);
    AbstractArcusResult<AttributesResult> result =
        new AbstractArcusResult<>(new AtomicReference<>());
    ArcusFutureImpl<AttributesResult> future = new ArcusFutureImpl<>(result);
    ArcusClient client = arcusClientSupplier.get();

    AttributesResult attributes = new AttributesResult();
    GetAttrOperation.Callback cb = new GetAttrOperation.Callback() {
      @Override
      public void gotAttribute(String key, String attr) {
        attributes.setAttribute(attr);
      }

      @Override
      public void receivedStatus(OperationStatus status) {
        switch (status.getStatusCode()) {
          case SUCCESS:
            result.set(attributes);
            break;
          case ERR_NOT_FOUND:
            result.set(null);
            break;
          case CANCELLED:
            future.internalCancel();
            break;
          default:
            /*
             * ATTR_ERROR or unknown statement.
             */
            result.addError(key, status);
        }
      }

      @Override
      public void complete() {
        future.complete();
      }
    };
    GetAttrOperation op = client.getOpFact().getAttr(key, cb);
    future.setOp(op);
    client.addOp(key, op);

    return future;
  }

@f1v3-dev f1v3-dev force-pushed the feat/v2-long-type-exp branch from df3b226 to dfb9f74 Compare July 9, 2026 03:33
@jhpark816

jhpark816 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Attr 관련 클래스 분할, 사용 용도는 확인해 보니 OK입니다.
남은 것은 용어 결정인데, 어렵네요.

  • AttributeClause -> AttributeIF
  • AttributesCreate -> CreateAttribute
  • AttributesUpdate -> UpdateAttribute (??)
  • AttributeResult -> RetrieveAttribute (??)

두 사람이 먼저 합의해 볼 수 있나요?

@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

AttributeClauseAttributeIF로 변경하기보다는,
역할이 더 명확히 드러나는 SetAttrClause로 변경하고 stringify() 메서드를 추가하는 방식은 어떨까요?

현재 AttributeClause는 실제로 setattr 명령에 들어갈 attribute clause 문자열을 생성하기 위한 인터페이스에 가깝습니다. 따라서 단순히 attribute를 표현하는 AttributeIF보다는, setattr 명령의 일부를 만든다는 의미가 드러나는 SetAttrClause가 더 적절해 보입니다.

public interface SetAttrClause {

  String stringify();

  int getLength();
}

기존 구조에서는 attrs 객체를 그대로 setArguments()에 넘기고, 내부적으로 String.valueOf(attrs)를 통해 attrs.toString()이 호출됩니다.

SetAttrOperationImpl
  -> setArguments(..., attrs)
  -> String.valueOf(attrs)
  -> attrs.toString()

즉, setattr 명령 문자열 생성이 toString()에 암묵적으로 의존하고 있습니다.

다만 toString()은 일반적으로 디버깅이나 사람이 읽기 쉬운 표현을 위한 용도로 사용되는 경우가 많기 때문에, 프로토콜 명령 문자열 생성 용도로 사용하기에는 의도가 불명확해 보입니다.

따라서 아래처럼 attrs.stringify()를 사용하면, attribute clause를 명령 문자열로 변환한다는 의도를 더 명시적으로 드러낼 수 있을 것 같습니다.

// as-is
setArguments(bb, "setattr", key, attrs);

// to-be
setArguments(bb, "setattr", key, attrs.stringify());

정리하면, SetAttrClause라는 이름으로 역할을 구체화하고, toString() 대신 stringify()를 사용해 setattr 명령 문자열 생성 의도를 명확히 하는 방향이 더 적절해 보입니다.

@jhpark816

jhpark816 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

@f1v3-dev
interface를 나타내는 용어로 Clause 라는 용어를 많이 사용하나요?

stringify() 메서드를 추가하는 것은 좋네요.

@jhpark816

jhpark816 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Attr 관련 클래스 분할, 사용 용도는 확인해 보니 OK입니다. 남은 것은 용어 결정인데, 어렵네요.

  • AttributeClause -> AttributeIF
  • AttributesCreate -> CreateAttribute
  • AttributesUpdate -> UpdateAttribute (??)
  • AttributeResult -> RetrieveAttribute (??)

두 사람이 먼저 합의해 볼 수 있나요?

AI에게 물어본 결과는 아래와 같고, 아래 용어가 괜찮은 것 같습니다.

  • CreateAttributes
  • UpdateAttributes
  • ItemAttributes

앞서 민경 전임의 제안과 유사한데,
attributes full name을 사용하는 것과 조회 결과에는 Item을 붙이자는 것입니다.

@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

@f1v3-dev interface를 나타내는 용어로 Clause 라는 용어를 많이 사용하나요?

stringify() 메서드를 추가하는 것은 좋네요.

Clause가 인터페이스를 나타내는 용어로 자주 사용되는 것은 아닙니다.

다만 현재 해당 인터페이스의 역할이 setattr 명령에 포함될 attribute 문자열 조각을 생성하는 것이기 때문에, “명령의 일부 절”이라는 의미에서 SetAttrClause라는 이름을 고려했습니다.

관례만 놓고 보면 인터페이스명에는 ~able, ~er, ~or 형태가 더 자주 사용되지만, 이 경우에는 인터페이스 자체를 드러내기보다는 해당 타입이 담당하는 역할을 표현하는 쪽이 더 적절하다고 판단했습니다.

@jhpark816

Copy link
Copy Markdown
Collaborator

CreateAttributes도 implement 해야 하는 interface이죠?
SetAttr는 너무 한정하는 것 같아서요.

@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

CreateAttributes도 implement 해야 하는 interface이죠?
SetAttr는 너무 한정하는 것 같아서요.

CreateAttributes는 사용하지 않는 interface입니다.

setattr 명령에서 사용되는 Attributes, UpdateAttributes 에서만 사용됩니다.

@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author
  • CreateAttributes
  • UpdateAttributes
  • ItemAttributes

클래스명을 해당 네이밍으로 변경하도록 하겠습니다.

@f1v3-dev f1v3-dev force-pushed the feat/v2-long-type-exp branch from dfb9f74 to b7041ab Compare July 9, 2026 08:21
@f1v3-dev f1v3-dev requested a review from oliviarla July 9, 2026 08:34
@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

해당 PR 이후 아래의 작업 이어서 진행하겠습니다.

  • v2 – getAttr, setAttr 구현
  • CollectionCreate 리팩토링 – makeCreateClause, checkOverflowAction 과 같은 static method

@jhpark816

Copy link
Copy Markdown
Collaborator

CreateAttributes는 사용하지 않는 interface입니다.

setattr 명령에서 사용되는 Attributes, UpdateAttributes 에서만 사용됩니다.

OK.
CreateAttributes도 결국 명령 문자열을 생성하여야 하므로 stringify() 메소드를 두겠지만,
setattr 명령 처리에서 다른 두 구현체를 받을 수 있도록 하기 위한 목적의 interface가 필요한 것이므로,
해당 interface는 Attributes, UpdateAttributes 에서만 implement 하게 할 것이라는 것이죠?

@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

CreateAttributes도 결국 명령 문자열을 생성하여야 하므로 stringify() 메소드를 두겠지만,
setattr 명령 처리에서 다른 두 구현체를 받을 수 있도록 하기 위한 목적의 interface가 필요한 것이므로,
해당 interface는 Attributes, UpdateAttributes 에서만 implement 하게 할 것이라는 것이죠?

네 맞습니다.

SetAttrClausesetattr 명령 처리에서 두 구현체(v1 – Attributes, v2 – UpdateAttributes)를 하나의 타입으로 받기 위한 인터페이스이므로, 이 둘에서만 사용합니다.

다만, 현재 구조에서는 create / insert-with-create의 경우 CollectionCreate.makeCreateClause()라는 정적 메서드로 문자열을 생성하고 있습니다.

해당 로직을 CreateAttributes 쪽으로 옮길 수는 있지만, 현재 PR의 범위가 더 커질 수 있기 때문에 이번 변경에는 포함하지 않고, 향후 아래와 같이 리팩토링할 예정입니다.

문자열(Clause) 생성 위치

  • as-is: CollectionCreate.makeCreateClause()
  • to-be: CreateAttributes.stringify()

@jhpark816

Copy link
Copy Markdown
Collaborator

@f1v3-dev
변경할 attributes를 나타내는 클래스의 interface이므로, Clause 용어 사용하는 것은 아무래도 어색해 보입니다.
interface 명으로 SetAttributes 용어를 사용하는 것이 더 적합해 보입니다. (의견 제시입니다.)
그리고, 이를 구현하는 클래스로 기존의 Attributes와 새로 추가하는 UpdateAttributes가 있습니다.

@f1v3-dev

f1v3-dev commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

@jhpark816

public interface SetAttrOperation extends KeyedOperation {

  SetAttrClause getAttributes();

}

이 인터페이스를 보니 어색해 보이기 때문에, 말씀해주신대로 SetAttributes 용어를 사용하는 방향으로 수정하는게 더 맞아보입니다.

수정하도록 하겠습니다.

@f1v3-dev f1v3-dev force-pushed the feat/v2-long-type-exp branch from b7041ab to bda88de Compare July 9, 2026 10:23
Comment thread src/main/java/net/spy/memcached/collection/BTreeInsertAndGet.java Outdated

@oliviarla oliviarla left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

최종 리뷰입니다.

Comment thread src/main/java/net/spy/memcached/OperationFactory.java
Comment thread src/test/java/net/spy/memcached/v2/attribute/UpdateAttributesTest.java Outdated
@f1v3-dev f1v3-dev force-pushed the feat/v2-long-type-exp branch from bda88de to 45290c1 Compare July 10, 2026 00:29
@f1v3-dev f1v3-dev requested a review from oliviarla July 10, 2026 00:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants